package lt.marsrutai.mobile.android.activity;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import lt.marsrutai.mobile.android.AppContext;
import lt.marsrutai.mobile.android.R;
import lt.marsrutai.mobile.android.activity.intent.SchedulesIntentHolder;
import lt.marsrutai.mobile.android.activity.intent.StopSearchIntentHolder;
import lt.marsrutai.mobile.android.adapter.TabAdapter;
import lt.marsrutai.mobile.android.adapter.TabInfoProvider;
import lt.marsrutai.mobile.android.cache.UpdateCacheRequest;
import lt.marsrutai.mobile.android.exception.DataAccessException;
import lt.marsrutai.mobile.android.fragment.SchedulesFragment;
import lt.marsrutai.mobile.android.handler.menu.MenuHandler;
import lt.marsrutai.mobile.android.handler.menu.SchedulesMenuHandler;
import lt.marsrutai.mobile.android.manager.ActivityManager;
import lt.marsrutai.mobile.android.model.Schedule;
import lt.marsrutai.mobile.android.service.TransportInfoResolver.TransportInfo;
import lt.marsrutai.mobile.android.util.PreferenceUtils;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.ViewPager;

import com.viewpagerindicator.TabPageIndicator;

public class SchedulesActivity extends BaseActivity {

    private ActivityManager manager;

    /** Schedules grouped by their transport types and ordered by {@link TransportInfo#getIndex()} */
    private Map<TransportInfo, List<Schedule>> groupedSchedules = new TreeMap<TransportInfo, List<Schedule>>(new Comparator<TransportInfo>() {

        @Override
        public int compare(TransportInfo arg0, TransportInfo arg1) {
            return arg0.getIndex() > arg1.getIndex() ? 1 : (arg0.getIndex() == arg1.getIndex() ? 0 : -1);
        }
        
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        manager = new ActivityManager(this);

        // Display loading in the temp view while the data is downloading
        setContentView(R.layout.progress_spinner);
        manager.showDownloadLoadingBar();

        downloadData();

        showDownloadAdvice();
    }

    /**
     * Creates tabs for each schedule group and initializes the adapter
     */
    private void initialize() {
        TabAdapter adapter = new TabAdapter(getSupportFragmentManager());

        for (Entry<TransportInfo, List<Schedule>> entry : groupedSchedules.entrySet()) {
            // Fill intent holder with proper info
            SchedulesIntentHolder intentHolder = new SchedulesIntentHolder(getIntent().getExtras());
            intentHolder.setSchedules(entry.getValue());
            
            // Add tab
            adapter.addTab(new TabInfoProvider(SchedulesFragment.class, 
                    intentHolder.getIntent().getExtras(), 
                    entry.getKey().getLocalizedNamePlural()));
        }

        // Attach the adapted to the view pager
        setContentView(R.layout.tabs_viewpager_layout);
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        viewPager.setAdapter(adapter);
        // Attach view pager to tab page indicator
        TabPageIndicator indicator = (TabPageIndicator) findViewById(R.id.indicator);
        indicator.setViewPager(viewPager);
    }

    private void downloadData() {
        Runnable downloadTask = new Runnable() {

            @Override
            public void run() {
                SchedulesIntentHolder schedulesIntentHolder = new SchedulesIntentHolder(getIntent().getExtras());
                String scope = schedulesIntentHolder.getScopeFolder();

                try {
                    // Group schedules
                    List<Schedule> routes = AppContext.getDataService().getSchedules(scope);
                    for (Schedule schedule : routes) {
                        TransportInfo transportInfo = AppContext.getTransportInfoResolver().getTransportInfo(scope, schedule.getTransportId());
                        if (!groupedSchedules.containsKey(transportInfo)) {
                            groupedSchedules.put(transportInfo, new ArrayList<Schedule>());
                        }
                        groupedSchedules.get(transportInfo).add(schedule);
                    }
                }
                catch (DataAccessException e) {
                    manager.runOnUiThread(manager.errorRes);
                    return;
                }
                manager.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        initialize();
                    }
                });
            }
        };
        Thread thread = new Thread(downloadTask);
        thread.start();
    }

    private void showDownloadAdvice() {
        if (Boolean.FALSE.equals(PreferenceUtils.getPreferenceValue(this, PreferenceUtils.SCHEDULE_ACTIVITY_OPENED))) {
            PreferenceUtils.setBooleanPreferenceValue(this, PreferenceUtils.SCHEDULE_ACTIVITY_OPENED, Boolean.TRUE);

            SchedulesIntentHolder sourceIntentHolder = new SchedulesIntentHolder(getIntent());
            AppContext.getCacheUpdateManager().showDownloadScopeAdviceDialog(
                    this,
                    new UpdateCacheRequest(sourceIntentHolder.getScopeFolder(), sourceIntentHolder.getScopeName(),
                            UpdateCacheRequest.Section.SCHEDULES));
        }
    }

    @Override
    public int getMenuResource() {
        return R.menu.schedules_menu;
    }

    @Override
    public MenuHandler getMenuHandler() {
        return new SchedulesMenuHandler();
    }

    @Override
    public boolean onNavigationItemSelected(int itemPosition, long itemId) {
        if (itemPosition == 1) {
            startActivity(new Intent(this, ScopesActivity.class));
        }
        return false;
    }

    @Override
    public NavMenuData getNavMenuData() {
        SchedulesIntentHolder schedulesIntentHolder = new SchedulesIntentHolder(getIntent());
        return new NavMenuData(new String[] { schedulesIntentHolder.getScopeName(), getString(R.string.home) });
    }

    @Override
    public boolean onSearchRequested() {
        SchedulesIntentHolder sourceIntentHolder = new SchedulesIntentHolder(getIntent());

        StopSearchIntentHolder stopSearchIntentHolder = new StopSearchIntentHolder(new Bundle());
        stopSearchIntentHolder.setScopeFolder(sourceIntentHolder.getScopeFolder());
        stopSearchIntentHolder.setScopeName(sourceIntentHolder.getScopeName());

        startSearch(null, false, stopSearchIntentHolder.getIntent().getExtras(), false);

        return true;
    };
}
